package com.geline.sqlbackup.util;

import com.alibaba.druid.DbType;
import com.alibaba.druid.util.MySqlUtils;
import com.alibaba.druid.util.OracleUtils;
import com.geline.sqlbackup.bean.TableColumnInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.jdbc.datasource.DataSourceUtils;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

/**
 * 数据源解析DDL信息工具
 * @author: mengx
 * @date: 2021/10/15 8:52
 */
@Slf4j
public class DataSourceDdlUtil {

    /**
     * 批量解析表DDL，返回DDL列表
     * @param dataSource
     * @param tableList
     * @return
     */
    public static List<String> parseTableDDLs(DataSource dataSource, List<String> tableList) {
        DbType dbType = JdbcDbTypeUtil.getDbTypeOfDruid(dataSource);
        log.info("========parse dbType = {}", dbType);
        Connection connection = null;
        switch (dbType) { //参考：DialectRegistry
            case oracle:
            case oceanbase_oracle: {
                try {
                    connection = DataSourceUtils.doGetConnection(dataSource);
                    List<String> tableDDL = OracleUtils.getTableDDL(connection, tableList);
                    return tableDDL;
                } catch (SQLException e) {
                    log.error(e.getMessage(), e);
                    throw new RuntimeException(e.getMessage());
                } finally {
                    try {
                        DataSourceUtils.doReleaseConnection(connection, dataSource);
                    } catch (SQLException e) {
                        log.error("fail to close connection", e);
                    }
                }
            }
            case mysql: { // case mariadb:
                try {
                    connection = DataSourceUtils.doGetConnection(dataSource);
                    List<String> tableDDL = MySqlUtils.getTableDDL(connection, tableList);
                    return tableDDL;
                } catch (SQLException e) {
                    log.error(e.getMessage(), e);
                    throw new RuntimeException(e.getMessage());
                } finally {
                    try {
                        DataSourceUtils.doReleaseConnection(connection, dataSource);
                    } catch (SQLException e) {
                        log.error("fail to close connection", e);
                    }
                }
            }
            case kingbase:{
                List<String> tableDdlList = new ArrayList<>();
                String schemaName = JdbcParseUtils.findSchemaName(dataSource);
                for(String table : tableList){
                    TableColumnInfo tableColumnInfo = KingbaseInformationUtil.parseTableColumnInfo(dataSource, table, false, true);
                    String tableDDL = KingbaseInformationUtil.buildTableDDL(tableColumnInfo, schemaName);
                    tableDdlList.add(tableDDL);
                }
                return tableDdlList;
            }
            case other:{
                log.warn("====================={}","DataSourceDdlUtil ---> parseTableDDLs ---> other");
                String schemaName = JdbcParseUtils.findSchemaName(dataSource);
                List<String> tableDdlList = new ArrayList<>();
                for(String table : tableList){
                    TableColumnInfo tableColumnInfo = ShenTongInformationUtil.parseTableColumnInfo(dataSource, table, false, true);
                    String tableDDL = ShenTongInformationUtil.buildTableDDL(tableColumnInfo, schemaName);
                    log.debug("====================={}","DataSourceDdlUtil ---> parseTableDDLs ---> tableDDL" + tableDDL);
                    tableDdlList.add(tableDDL);
                }

                return tableDdlList;
            }
            default:{
                List<String> tableDdlList = new ArrayList<>();
                for(String table : tableList){
                    TableColumnInfo tableColumnInfo = MysqlInformationUtil.parseTableColumnInfo(dataSource, table, false, true);
                    String tableDDL = MysqlInformationUtil.buildTableDDL(tableColumnInfo);
                    tableDdlList.add(tableDDL);
                }
                return tableDdlList;
            }
        }
    }

    /**
     * 解析获取 TableColumnInfo
     * @param dataSource
     * @param table
     * @param useRemoveTableHead
     * @param useCamelCase
     * @return
     */
    public static TableColumnInfo parseTableColumnInfo(DataSource dataSource, String table, boolean useRemoveTableHead, boolean useCamelCase) {
        DbType dbType = JdbcDbTypeUtil.getDbTypeOfDruid(dataSource);
        if (dbType == DbType.kingbase) {
            return KingbaseInformationUtil.parseTableColumnInfo(dataSource, table, useRemoveTableHead, useCamelCase);
        } else if (dbType == DbType.other) {
            return ShenTongInformationUtil.parseTableColumnInfo(dataSource, table, useRemoveTableHead, useCamelCase);
        } else {
            return MysqlInformationUtil.parseTableColumnInfo(dataSource, table, useRemoveTableHead, useCamelCase);
        }
    }

    /**
     * 解析获取序列脚本
     *  shunde-oa有出现 can not find dba_sequences；建议使用异常捕获处理
     *
     * @param dataSource
     * @return
     */
    public static String parseSequenceDDLs(DataSource dataSource){
        DbType dbType = JdbcDbTypeUtil.getDbTypeOfDruid(dataSource);
        try{
            if(dbType == DbType.kingbase){
                // return KingbaseInformationUtil.parseSequenceInfo(dataSource);
            } else if(dbType == DbType.other) {  // shentong ---> oscard
                return ShenTongInformationUtil.parseSequenceInfo(dataSource);
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }

}
